Completed
Push — master ( 900d15...0f80c8 )
by Sander
12s
created

angular.controller(ꞌShareCtrlꞌ)   D

Complexity

Conditions 8
Paths 576

Size

Total Lines 355

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 8
c 3
b 0
f 0
nc 576
nop 10
dl 0
loc 355
rs 4

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
/**
2
 * Nextcloud - passman
3
 *
4
 * @copyright Copyright (c) 2016, Sander Brand ([email protected])
5
 * @copyright Copyright (c) 2016, Marcos Zuriaga Miguel ([email protected])
6
 * @license GNU AGPL version 3 or any later version
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License as
10
 * published by the Free Software Foundation, either version 3 of the
11
 * License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
23
(function () {
24
	'use strict';
25
26
	/**
27
	 * @ngdoc function
28
	 * @name passmanApp.controller:MainCtrl
29
	 * @description
30
	 * # MainCtrl
31
	 * Controller of the passmanApp
32
	 * This file is part of passman, licensed under AGPLv3
33
	 */
34
	angular.module('passmanApp')
35
		.controller('ShareCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'ShareService', 'NotificationService', 'SharingACL', 'EncryptService',
36
			function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, ShareService, NotificationService, SharingACL, EncryptService) {
37
				$scope.active_vault = VaultService.getActiveVault();
38
39
				$scope.tabs = [{
40
					title: 'Share with users and groups',
41
					url: 'views/partials/forms/share_credential/basics.html'
42
				}, {
43
					title: 'Share link',
44
					url: 'views/partials/forms/share_credential/link_sharing.html',
45
					color: 'green'
46
				}];
47
				$scope.currentTab = {
48
					title: 'General',
49
					url: 'views/partials/forms/share_credential/basics.html'
50
				};
51
52
				$scope.onClickTab = function (tab) {
53
					$scope.currentTab = tab;
54
				};
55
56
				$scope.isActiveTab = function (tab) {
57
					return tab.url === $scope.currentTab.url;
58
				};
59
60
				if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
61
					if (!$scope.active_vault) {
62
						$location.path('/');
63
					}
64
				} else {
65
					if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
66
						var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
67
						_vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
68
						VaultService.setActiveVault(_vault);
69
						$scope.active_vault = _vault;
70
71
					}
72
				}
73
				var storedCredential = SettingsService.getSetting('share_credential');
74
75
				if (!storedCredential) {
76
					$location.path('/vault/' + $routeParams.vault_id);
77
				} else {
78
					$scope.storedCredential = CredentialService.decryptCredential(angular.copy(storedCredential));
79
				}
80
81
				if ($scope.active_vault) {
82
					$scope.$parent.selectedVault = true;
83
				}
84
				$scope.cancel = function () {
85
					SettingsService.setSetting('share_credential', null);
86
					$location.path('/vault/' + $routeParams.vault_id);
87
				};
88
89
90
				$scope.default_permissions = new SharingACL(0);
91
				$scope.default_permissions.addPermission(
92
					$scope.default_permissions.permissions.READ |
93
					$scope.default_permissions.permissions.WRITE |
94
					$scope.default_permissions.permissions.FILES
95
				);
96
97
				var link_acl = angular.copy($scope.default_permissions);
98
				link_acl.removePermission($scope.default_permissions.permissions.WRITE);
99
100
				$scope.share_settings = {
101
					linkSharing: {
102
						enabled: false,
103
						settings: {
104
							expire_time: new Date("2999-12-31T22:59:59"),
105
							expire_views: 5,
106
							acl: link_acl
107
						}
108
					},
109
					credentialSharedWithUserAndGroup: [],
110
					cypher_progress: {
111
						done: 0,
112
						total: 0
113
					},
114
					upload_progress: {
115
						done: 0,
116
						total: 0
117
					}
118
				};
119
120
				var getAcl = function () {
121
					ShareService.getSharedCredentialACL($scope.storedCredential).then(function (aclList) {
122
						var _list = [];
123
						var enc_key = ($scope.storedCredential.shared_key) ? EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key)) : false;
124
						for (var i = 0; i < aclList.length; i++) {
125
							var acl = aclList[i];
126
							if (acl.user_id === null) {
127
								$scope.share_settings.linkSharing = {
128
									enabled: true,
129
									settings: {
130
										expire_time: new Date(acl.expire * 1000),
131
										expire_views: acl.expire_views,
132
										acl: new SharingACL(acl.permissions)
133
									}
134
								};
135
								if (enc_key) {
136
									var hash = window.btoa($scope.storedCredential.guid + '<::>' + enc_key);
137
									$scope.share_link = getShareLink(hash);
138
								}
139
							} else {
140
								var obj = {
141
									userId: acl.user_id,
142
									displayName: acl.user_id,
143
									type: 'user',
144
									acl: new SharingACL(acl.permissions),
145
									acl_id: acl.acl_id,
146
									pending: acl.pending,
147
									credential_guid: acl.item_guid,
148
									created: acl.created
149
								};
150
151
								_list.push(obj);
152
							}
153
154
						}
155
						$scope.share_settings.credentialSharedWithUserAndGroup = _list;
156
					});
157
				};
158
				getAcl();
159
				var acl = new SharingACL(0);
160
161
162
				$scope.$watch('share_settings.upload_progress.done', function () {
163
										if ($scope.share_settings.upload_progress.done === $scope.share_settings.upload_progress.total && $scope.share_settings.upload_progress.total > 0) {
164
						getAcl();
165
					}
166
				});
167
168
				$scope.inputSharedWith = [];
169
170
				$scope.searchUsers = function ($query) {
171
					return ShareService.search($query);
172
				};
173
174
				$scope.hasPermission = function (acl, permission) {
175
					return acl.hasPermission(permission);
176
				};
177
178
				$scope.setPermission = function (acl, permission) {
179
					acl.togglePermission(permission);
180
				};
181
				$scope.shareWith = function (shareWith) {
182
					$scope.inputSharedWith = [];
183
					if (shareWith.length > 0) {
184
						for (var i = 0; i < shareWith.length; i++) {
185
							var obj = {
186
								userId: shareWith[i].uid,
187
								displayName: shareWith[i].text,
188
								type: shareWith[i].type,
189
								acl: angular.copy($scope.default_permissions),
190
								pending: true,
191
								credential_guid: $scope.storedCredential.guid
192
							};
193
							var found = false;
194
							for (var z = 0; z < $scope.share_settings.credentialSharedWithUserAndGroup.length; z++) {
195
								if ($scope.share_settings.credentialSharedWithUserAndGroup[z].userId === shareWith[z].uid) {
196
									found = true;
197
								}
198
							}
199
							if (found === false) {
200
								$scope.share_settings.credentialSharedWithUserAndGroup.push(obj);
201
							}
202
						}
203
					}
204
				};
205
206
				$scope.unshareUser = function (user) {
207
					ShareService.unshareCredentialFromUser($scope.storedCredential, user.userId).then(function (result) {
208
						if (result.result === true) {
209
							var idx = $scope.share_settings.credentialSharedWithUserAndGroup.indexOf(user);
210
							$scope.share_settings.credentialSharedWithUserAndGroup.splice(idx, 1);
211
						}
212
					});
213
				};
214
215
				$scope.unshareCredential = function (credential) {
216
					ShareService.unshareCredential(credential);
217
					var _credential = angular.copy(credential);
218
					var old_key = EncryptService.decryptString(angular.copy(_credential.shared_key));
219
					var new_key = VaultService.getActiveVault().vaultKey;
220
					_credential.shared_key = null;
221
					_credential.unshare_action = true;
222
					_credential.skip_revision = true;
223
224
					_credential = CredentialService.encryptCredential(_credential, old_key);
225
					CredentialService.updateCredential(_credential, true).then(function () {
226
						NotificationService.showNotification('Credential unshared', 4000);
227
						CredentialService.reencryptCredential(_credential.guid, old_key, new_key).then(function () {
228
							getAcl();
229
						});
230
					});
231
				};
232
233
				/**
234
				 * Apply a share to a new user
235
				 * @param user A user object to who we should share the data
236
				 * @param enc_key The shared key we are going to ecnrypt with his public rsa key
237
				 */
238
				$scope.applyShareToUser = function (user, enc_key) {
239
					ShareService.getVaultsByUser(user.userId).then(function (data) {
240
						$scope.share_settings.cypher_progress.total += data.length;
241
242
						user.vaults = data;
243
						var start = new Date().getTime() / 1000;
244
						ShareService.cypherRSAStringWithPublicKeyBulkAsync(user.vaults, enc_key)
245
							.progress(function () {
246
								$scope.share_settings.cypher_progress.done++;
247
								$scope.share_settings.cypher_progress.percent = $scope.share_settings.cypher_progress.done / $scope.share_settings.cypher_progress.total * 100;
248
								$scope.$digest();
249
							})
250
							.then(function (result) {
251
																$scope.share_settings.cypher_progress.times.push({
252
									time: ((new Date().getTime() / 1000) - start),
253
									user: data[0].user_id
254
								});
255
								user.vaults = result;
256
								if (!user.hasOwnProperty('acl_id')) {
257
									$scope.uploadChanges(user);
258
								}
259
								$scope.$digest();
260
							});
261
					});
262
				};
263
264
265
266
				$scope.$on("$locationChangeStart", function(event) {
267
					if(!$scope.sharing_complete){
268
						if(!confirm("Are you sure you want to leave?\nThis will corrupt this credential")){
269
							event.preventDefault();
270
						}
271
					}
272
				});
273
274
				var getShareLink = function(hash){
275
					var port;
276
					var defaultPort = ($location.$$protocol === 'http') ? 80 : 443;
277
					port = (defaultPort !== $location.$$port) ? ':'+ $location.$$port : '';
278
					return $location.$$protocol + '://' + $location.$$host + port + OC.generateUrl('apps/passman/share/public#') + hash;
279
				};
280
281
				$scope.sharing_complete = true;
282
				$scope.applyShare = function () {
283
					$scope.sharing_complete = false;
284
					$scope.share_settings.cypher_progress.percent = 0;
285
					$scope.share_settings.cypher_progress.done = 0;
286
					$scope.share_settings.cypher_progress.total = 0;
287
					$scope.share_settings.cypher_progress.times = [];
288
					$scope.share_settings.cypher_progress.times_total = [];
289
					$scope.share_settings.upload_progress.done = 0;
290
					$scope.share_settings.upload_progress.total = 0;
291
					//Credential is already shared
292
					if ($scope.storedCredential.shared_key && $scope.storedCredential.shared_key !== '' && $scope.storedCredential.shared_key !== null) {
293
												var enc_key = EncryptService.decryptString(angular.copy($scope.storedCredential.shared_key));
294
						if ($scope.share_settings.linkSharing.enabled) {
295
							var expire_time = new Date(angular.copy($scope.share_settings.linkSharing.settings.expire_time)).getTime() / 1000;
296
							var shareObj = {
297
								item_id: $scope.storedCredential.credential_id,
298
								item_guid: $scope.storedCredential.guid,
299
								permissions: $scope.share_settings.linkSharing.settings.acl.getAccessLevel(),
300
								expire_timestamp: expire_time,
301
								expire_views: $scope.share_settings.linkSharing.settings.expire_views
302
							};
303
							ShareService.createPublicSharedCredential(shareObj).then(function () {
304
								var hash = window.btoa($scope.storedCredential.guid + '<::>' + enc_key);
305
								$scope.share_link = getShareLink(hash);
306
							});
307
						}
308
309
						var list = $scope.share_settings.credentialSharedWithUserAndGroup;
310
311
						for (var i = 0; i < list.length; i++) {
312
							var iterator = i;
313
							var target_user = list[i];
314
							if (target_user.hasOwnProperty('created')) {
315
								var acl = {
316
									user_id: target_user.userId,
317
									permission: target_user.acl.getAccessLevel()
318
								};
319
								ShareService.updateCredentialAcl($scope.storedCredential, acl);
320
							} else {
321
								$scope.applyShareToUser(list[iterator], enc_key);
322
							}
323
						}
324
						NotificationService.showNotification('Saved!', 4000);
325
						$scope.sharing_complete = true;
326
					} else {
327
328
						ShareService.generateSharedKey(20).then(function (key) {
329
330
							var encryptedSharedCredential = angular.copy($scope.storedCredential);
331
							var old_key = VaultService.getActiveVault().vaultKey;
332
333
							CredentialService.reencryptCredential(encryptedSharedCredential.guid, old_key, key).progress(function () {
334
															}).then(function (data) {
335
								var _credential = data.cryptogram;
336
								_credential.set_share_key = true;
337
								_credential.skip_revision = true;
338
								_credential.shared_key = EncryptService.encryptString(key);
339
								CredentialService.updateCredential(_credential, true).then(function () {
340
									NotificationService.showNotification('Credential shared', 4000);
341
									$scope.sharing_complete = true;
342
								});
343
							});
344
345
							var list = $scope.share_settings.credentialSharedWithUserAndGroup;
346
							for (var i = 0; i < list.length; i++) {
347
								if (list[i].type === "user") {
348
									$scope.applyShareToUser(list[i], key);
349
								}
350
							}
351
352
							if ($scope.share_settings.linkSharing.enabled) {
353
								var expire_time = new Date(angular.copy($scope.share_settings.linkSharing.settings.expire_time)).getTime() / 1000;
354
								var shareObj = {
355
									item_id: $scope.storedCredential.credential_id,
356
									item_guid: $scope.storedCredential.guid,
357
									permissions: $scope.share_settings.linkSharing.settings.acl.getAccessLevel(),
358
									expire_timestamp: expire_time,
359
									expire_views: $scope.share_settings.linkSharing.settings.expire_views
360
								};
361
								ShareService.createPublicSharedCredential(shareObj).then(function () {
362
									var hash = window.btoa($scope.storedCredential.guid + '<::>' + key);
363
									$scope.share_link = getShareLink(hash);
364
								});
365
							}
366
367
						});
368
					}
369
				};
370
371
				$scope.uploadChanges = function (user) {
372
					$scope.share_settings.upload_progress.total++;
373
374
					user.accessLevel = angular.copy(user.acl.getAccessLevel());
375
					ShareService.shareWithUser(storedCredential, user)
376
						.then(function () {
377
							$scope.share_settings.upload_progress.done++;
378
							$scope.share_settings.upload_progress.percent = $scope.share_settings.upload_progress.done / $scope.share_settings.upload_progress.total * 100;
379
						});
380
				};
381
382
				$scope.calculate_total_time = function () {
383
					$scope.share_settings.cypher_progress.times = $scope.share_settings.cypher_progress.times || [];
384
					var total = 0;
385
					for (var i = 0; i < $scope.share_settings.cypher_progress.times.length; i++) {
386
						total += $scope.share_settings.cypher_progress.times[i].time;
387
					}
388
					return total;
389
				};
390
			}]);
391
}());
392